using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Xml;

namespace ScreenMonkey.Plugin.Clips.Song
{
    public class VerseLabel
    {
        public event EventHandler NameChanged;

        public VerseLabel(string name, string quickName)
        {
            this.Name = name;
            this.QuickName = quickName;
        }

        public VerseLabel(XmlNode xml)
        {
            LoadXml(xml);
        }

        private bool strict = false;

        /// <summary>
        /// Gets or sets whether to use strict error checking when this item is changed.
        /// </summary>
        internal bool Strict 
        {
            get
            {
                return strict;
            }
            set
            {
                strict = value;
            }
        }

        [Browsable(false)]
        public string Id
        {
            get { return name.Replace(" ",""); }
        }

        [Browsable(false)]
        public Guid GlobalId { get; set; }

        private string name = "Plain Text";

        [Category("Tag"), Description("The name of the tag used to identify the start of the verse.")]
        public string Name
        {
            get { return name; }
            set {
                value = value.Trim();

                if (string.IsNullOrEmpty(value))
                    throw new ArgumentException("The name for a label can not be a blank string!");

                VerseLabel conflictingLabel = VerseLabels.FindLabel(value);
                if (Strict && conflictingLabel != null && conflictingLabel != this)
                    throw new ArgumentException(string.Format("A label already exists with the name '{0}'. Please use a different name.", value));

                if (name != value)
                {
                    name = value;
                    if (NameChanged != null) NameChanged(this, EventArgs.Empty);
                }
            }
        }

        private String quickName = "P";

        [Category("Tag"), Description("A short tag which must be enclosed in [] (e.g. [V1]) when editting lyrics.")]
        public String QuickName
        {
            get { return quickName; }
            set {
                if (value.Length > 1)
                    throw new ArgumentException("The quick name must be no longer than a single character. Try using '{0}'.", value.Substring(0, 1));

                VerseLabel conflictingLabel = VerseLabels.FindQuickName(value);
                if (Strict && conflictingLabel != null && conflictingLabel != this)
                    throw new ArgumentException(string.Format("A label already exists with the quick name '{0}'. Please use a different name.",value));

               
                quickName = value; 
            }
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj is VerseLabel) return ((VerseLabel)obj).Id == Id;

            return base.Equals(obj);
        }

        public override string ToString()
        {
            return Name;
        }

        public static bool TryParse(string item, out VerseLabel newItem)
        {
            newItem = null;

            if(!string.IsNullOrEmpty(item))
            {
                foreach (VerseLabel label in VerseLabels.Labels)
                {
                    if ((!string.IsNullOrEmpty(label.Name) && label.Name.ToUpper() == item.ToUpper())
                        || (!string.IsNullOrEmpty(label.QuickName) && string.Format("[" + label.QuickName.ToUpper() + "]")== item.ToUpper()))
                    {
                        newItem = label;
                        return true;
                    }
                }
            }

            return false;
        }

        #region Save and Load

        public void SaveXml(XmlWriter writer)
        {
            writer.WriteStartElement("tag");
            writer.WriteAttributeString("name", Name);
            writer.WriteAttributeString("quickName", QuickName);
            writer.WriteAttributeString("globalId", GlobalId.ToString());
            writer.WriteEndElement();
        }

        public void LoadXml(XmlNode xml)
        {
            XmlNode nameXml = xml.SelectSingleNode("@name");
            XmlNode quickNameXml = xml.SelectSingleNode("@quickName");
            XmlNode globalIdXml = xml.SelectSingleNode("@globalId");

            if (nameXml != null)
            {
                Name = nameXml.Value;
                if (quickNameXml != null) QuickName = quickNameXml.Value;
            }

            //Load or initialise the guid.
            GlobalId = globalIdXml == null ? Guid.NewGuid() : new Guid(globalIdXml.Value);
        }

        #endregion


        private static VerseLabel empty = new VerseLabel("Empty", "E");

        public static VerseLabel Empty
        {
            get
            {
                return empty;
            }
        }

        private static VerseLabel plainText = new VerseLabel("Plain Text", "P");

        public static VerseLabel PlainText
        {
            get
            {
                return plainText;
            }
        }
    }
}
